package crud.client.dialog;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.menu.Menu;
import com.smartgwt.client.widgets.menu.MenuButton;
import com.smartgwt.client.widgets.menu.MenuItem;
import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent;

import crud.client.NormasysCRUD;
import crud.client.constant.CstExport;
import crud.client.constant.CstTypeEdition;
import crud.client.data.Colonne;
import crud.client.data.LigneDonnee;
import crud.client.data.Table;
import crud.client.data.authentication.Right;
import crud.client.event.ColumnInitEvent;
import crud.client.event.SaveEvent;
import crud.client.service.ServiceLocator;
import crud.client.util.GenericCallback;

public class TableCRUD extends GenericTableCRUD
{
	private final Label informationLabel = new Label();

	private IButton cancelButton;
	private IButton saveButton;
	private IButton editButton;
	private IButton deleteButton;
	private IButton newButton;
	private MenuButton menuButton;
	private final TableListGrid dataGrid;
	private int numberOfColumnInitialized = 0;

	public TableCRUD(final Table table, final List<Colonne> colonneList)
	{
		super(table, colonneList);
		dataGrid = new TableListGrid(table, colonneList);
	}

	@Override
	public void initialize(final NormasysCRUD parentNormasysCRUD, int left, int top)
	{
		super.initialize(parentNormasysCRUD, left, top);

		parentNormasysCRUD.getHandlerManager().addHandler(SaveEvent.getType(), new SaveEvent.SaveEventHandler()
		{
			public void onSave(SaveEvent event)
			{
				// Rechargement de la table maitre
				if (TableCRUD.this.isVisible() == true && event.getTableCRUD().getTable().equals(table))
				{
					reloadData();
				}

				// Rechargement d'une table dépendante
				if (TableCRUD.this.isVisible() == true && event.getTableCRUD().getTable().depends(table.getMappingClassName()))
				{
					reloadData();
					setInformation("Suite &agrave; la sauvegarde de la table " + event.getTableCRUD().getTable().getLibelle() + " la table &agrave; &eacute;t&eacute; recharg&eacute;e");
				}
			}
		});

		parentNormasysCRUD.getHandlerManager().addHandler(ColumnInitEvent.getType(), new ColumnInitEvent.ColumnInitEventHandler()
		{
			public synchronized void onColumnInit(ColumnInitEvent event)
			{
				// Si on est sur la bonne table
				if (event.getTableCRUD().getTable().equals(table))
				{
					numberOfColumnInitialized++;

					if (numberOfColumnInitialized >= colonneList.size())
					{
						numberOfColumnInitialized = 0;
						reloadData();
						TableCRUD.this.draw();
					}
				}

			}
		});

		// Initialisation des colonnes
		for (Colonne colonne : colonneList)
		{
			colonne.getFormItemFactory().initialize(colonne, parentNormasysCRUD.getHandlerManager(), new ColumnInitEvent(this, colonne));
		}

		this.addChild(dataGrid);

		// Le bouton annuler
		cancelButton = new IButton("Annuler");
		cancelButton.addClickHandler(new ClickHandler()
		{
			public void onClick(ClickEvent event)
			{
				dataGrid.reloadData();
				setInformation("Donn&eacute;es recharg&eacute;es");
			}
		});
		addChild(cancelButton);

		// Le bouton nouveau
		newButton = new IButton("Nouveau");
		newButton.addClickHandler(new ClickHandler()
		{
			public void onClick(ClickEvent event)
			{
				resetMessage();
				new TableLine(TableCRUD.this, CstTypeEdition.NOUVEAU);
			}
		});

		// Le bouton editer
		editButton = new IButton("Editer");
		editButton.setLeft(230);
		editButton.addClickHandler(new ClickHandler()
		{
			public void onClick(ClickEvent event)
			{
				resetMessage();
				ListGridRecord selectedRecord = dataGrid.getSelectedRecord();

				// Aucune ligne sélectionnée
				if (selectedRecord == null)
				{
					setError("Aucune ligne s&eacute;lectionn&eacute;e. Edition impossible");
					return;
				}

				String selectedPk = dataGrid.extractPK(selectedRecord);
				final LigneDonnee ligneDonnee = dataGrid.getCorrespondingLigneDonnee(selectedPk);

				@SuppressWarnings("unused")
				GenericCallback<Boolean> dataUsedCallback = new GenericCallback<Boolean>()
				{
					@Override
					public void onSuccess(Boolean isDataUsed)
					{
						TableLine tableLine = new TableLine(TableCRUD.this, ligneDonnee, isDataUsed, CstTypeEdition.EDITION);
					}

				};
				ServiceLocator.getServiceBase().isDataUsed(table, ligneDonnee, dataUsedCallback);

			}
		});

		// Le bouton supprimer
		deleteButton = new IButton("Supprimer");
		deleteButton.addClickHandler(new ClickHandler()
		{
			public void onClick(ClickEvent event)
			{
				resetMessage();
				final ListGridRecord selectedRecord = dataGrid.getSelectedRecord();

				if (selectedRecord == null)
				{
					setError("Aucune ligne s&eacute;lectionn&eacute;e. Suppression impossible");
					return;
				}

				// Sauvegarde
				LigneDonnee ligneDonneeToCheck = dataGrid.getLigneDonnee(selectedRecord);
				GenericCallback<Boolean> dataUsedCallback = new GenericCallback<Boolean>()
				{
					@Override
					public void onSuccess(Boolean isDataUsed)
					{
						if (isDataUsed == false)
						{
							String selectedPk = dataGrid.extractPK(selectedRecord);
							dataGrid.removeDataByPk(selectedPk);
							setInformation("Ligne supprim&eacute;e");
						} else
						{
							setError("Suppression impossible: cette donns&eacute;e est utilis&eacute;e dans une des tables d&eacute;pendantes");
						}
					}

				};
				ServiceLocator.getServiceBase().isDataUsed(table, ligneDonneeToCheck, dataUsedCallback);

			}
		});

		// Le bouton sauvegarder
		saveButton = new IButton("Sauvegarder");
		saveButton.addClickHandler(new ClickHandler()
		{
			public void onClick(ClickEvent event)
			{
				List<LigneDonnee> ligneDonneeList = new ArrayList<LigneDonnee>();

				for (int cp = 0; cp <= dataGrid.getTotalRows() - 1; cp++)
				{
					ListGridRecord record = (ListGridRecord) dataGrid.getEditedRecord(cp);

					LigneDonnee ligneDonnee = dataGrid.getLigneDonnee(record);
					ligneDonneeList.add(ligneDonnee);
				}

				// Sauvegarde
				GenericCallback<Void> sauvegardeCallback = new GenericCallback<Void>()
				{
					@Override
					public void onSuccess(Void colonneList)
					{
						// Sauvegarde dans la liste
						dataGrid.saveAllEdits();
						dataGrid.getLigneDonneToDeleteList().clear();
						setInformation("Sauvegarde&nbsp;effectu&eacute;e");

						// Envoi d'un évennement de MAJ aux autres fenétres pour que celles- se etent éventuellemnt é jour ....
						parentNormasysCRUD.getHandlerManager().fireEvent(new SaveEvent(TableCRUD.this));
					}

				};
				ServiceLocator.getServiceBase().updateData(table, dataGrid.getLigneDonneToDeleteList(), ligneDonneeList, sauvegardeCallback);

			}
		});

		if (Right.MODIFICATION.equals(getTable().getRight()))
		{
			addChild(deleteButton);
			addChild(editButton);
			addChild(newButton);
			addChild(saveButton);
		}

		// L'export des données
		Menu exportMemu = new Menu();
		exportMemu.setShowShadow(true);
		exportMemu.setShadowDepth(10);
		exportMemu.setTitle("Export");

		MenuItem csvItem = new MenuItem("csv", "/img/csv.png");
		MenuItem pdfItem = new MenuItem("pdf", "/img/pdf.jpg");
		exportMemu.setItems(csvItem, pdfItem);

		csvItem.addClickHandler(new com.smartgwt.client.widgets.menu.events.ClickHandler()
		{
			public void onClick(final MenuItemClickEvent event)
			{
				final String fileName = getTable().getLibelle();
				com.google.gwt.user.client.Window.open(GWT.getModuleBaseURL() + "export?type=" + CstExport.EXCEL + "&fileName=\"" + fileName + "\"&separator=" + CstExport.SEPARATOR + "&donnee=" + dataGrid.getExport(CstExport.SEPARATOR), "_self", "");
			}
		});

		pdfItem.addClickHandler(new com.smartgwt.client.widgets.menu.events.ClickHandler()
		{
			public void onClick(final MenuItemClickEvent event)
			{
				final String fileName = getTable().getLibelle();
				com.google.gwt.user.client.Window.open(GWT.getModuleBaseURL() + "export?type=" + CstExport.PDF + "&fileName=\"" + fileName + "\"&separator=" + CstExport.SEPARATOR + "&donnee=" + dataGrid.getExport(CstExport.SEPARATOR), "_blank", "");
			}
		});
		menuButton = new MenuButton("Export", exportMemu);
		addChild(menuButton);

		// Le champ d'information
		addChild(informationLabel);
		informationLabel.setLeft(10);
		informationLabel.setWidth100();
		informationLabel.setHeight(20);

		// Les positionnements
		dataGrid.setTop(30);
		dataGrid.setLeft(10);
		dataGrid.setHeight(200);

		informationLabel.setTop(dataGrid.getTop() + dataGrid.getHeight() + 10);

		int bottomButtonTop = informationLabel.getTop() + informationLabel.getHeight() + 10;
		int rightButtonLeft = dataGrid.getLeft() + dataGrid.getWidth() + 10;
		int buttonHeight = cancelButton.getHeight();
		int buttonWidth = cancelButton.getWidth();
		cancelButton.setTop(bottomButtonTop);
		saveButton.setTop(bottomButtonTop);
		menuButton.setTop(dataGrid.getTop());
		newButton.setTop(menuButton.getTop() + 50);
		editButton.setTop(newButton.getTop() + buttonHeight + 10);
		deleteButton.setTop(editButton.getTop() + buttonHeight + 10);

		cancelButton.setLeft(10);
		menuButton.setLeft(rightButtonLeft);
		saveButton.setLeft(rightButtonLeft);
		newButton.setLeft(rightButtonLeft);
		editButton.setLeft(rightButtonLeft);
		deleteButton.setLeft(rightButtonLeft);
		this.setWidth(newButton.getLeft() + buttonWidth + 20);
		this.setHeight(bottomButtonTop + buttonHeight + 10);

		this.draw();
	}

	public void setInformation(String informationText)
	{
		informationLabel.setContents("<span style=\"color: green;\">" + informationText + "</span><br/>");
	}

	public void setError(String informationText)
	{
		informationLabel.setContents("<span style=\"color: red;\">" + informationText + "</span><br/>");
	}

	private void resetMessage()
	{
		informationLabel.setContents("");
	}

	public Table getTable()
	{
		return dataGrid.getTable();
	}

	public List<Colonne> getColonneList()
	{
		return dataGrid.getColonneList();
	}

	public List<Colonne> getPkList()
	{
		return dataGrid.getPkList();
	}

	public List<Colonne> getNonPkList()
	{
		return dataGrid.getNonPkList();

	}

	public void addOrReplaceData(LigneDonnee ligneDonnee, String oldPk)
	{
		this.dataGrid.addOrReplaceData(ligneDonnee, oldPk);
	}

	public void addOrReplaceData(LigneDonnee ligneDonnee, Integer lineNumber)
	{
		this.dataGrid.addOrReplaceData(ligneDonnee, lineNumber);
	}

	public void addData(LigneDonnee ligneDonnee)
	{
		this.dataGrid.addData(ligneDonnee);
	}

	public ListGridRecord getCorrespondingRecord(LigneDonnee ligneDonnee)
	{
		return dataGrid.getCorrespondingRecord(ligneDonnee);
	}

	public String extractPK(LigneDonnee ligneDonnee)
	{
		return dataGrid.extractPK(ligneDonnee);
	}

	public void reloadData()
	{
		dataGrid.reloadData();
	}
}
